package com.ycyoes.demos.map;

import java.awt.geom.Point2D;
import java.lang.Math;
import java.util.ArrayList;
import java.util.List;

public class GraphUtils {
    /**
     * 默认地球半径
     */
    private static final double EARTH_RADIUS = 6378.137;//赤道半径(单位m)

    public static void main(String[] args) {
        Point2D.Double point = new Point2D.Double(116.434164,39.910065);
        Point2D.Double point2 = new Point2D.Double(116.416342,39.891909);
        Point2D.Double point3 = new Point2D.Double(116.442788,39.887923);
        Point2D.Double point4 = new Point2D.Double(116.477858,39.893238);
        Point2D.Double point5 = new Point2D.Double(116.369774,39.892352);
        Point2D.Double point6 = new Point2D.Double(116.369774,39.892352);
        Point2D.Double point7 = new Point2D.Double(116.416342,39.958308);
        Point2D.Double point8 = new Point2D.Double(116.46406,39.930429);

//        Point point1 = new Point(116.554322,39.900323);
//        Point point2 = new Point(116.405994,39.948131);
//        System.out.println(getDistance(point1.getLongitude(), point1.getLatitude(), point.getLongitude(), point.getLatitude()));
        List<Point2D.Double> polygon = new ArrayList<>();
        polygon.add(point2);
        polygon.add(point3);
        polygon.add(point4);
        polygon.add(point5);
        polygon.add(point6);
        polygon.add(point7);
        polygon.add(point8);
        System.out.println(check(point, polygon));

    }

    /**
     * 一个点是否在多边形内
     *
     * @param point   要判断的点的横纵坐标
     * @param polygon 组成的顶点坐标集合
     * @return
     */
    private static boolean check(Point2D.Double point, List<Point2D.Double> polygon) {
        java.awt.geom.GeneralPath peneralPath = new java.awt.geom.GeneralPath();

        Point2D.Double first = polygon.get(0);
        // 通过移动到指定坐标（以双精度指定），将一个点添加到路径中
        peneralPath.moveTo(first.x, first.y);
        polygon.remove(0);
        for (Point2D.Double d : polygon) {
            // 通过绘制一条从当前坐标到新指定坐标（以双精度指定）的直线，将一个点添加到路径中。
            peneralPath.lineTo(d.x, d.y);
        }
        // 将几何多边形封闭
        peneralPath.lineTo(first.x, first.y);
        peneralPath.closePath();
        // 测试指定的 Point2D 是否在 Shape 的边界内。
        return peneralPath.contains(point);
    }

    /**
     * 目标点是否在目标边上边上<br/>
     *
     * @param px0 目标点的经度坐标
     * @param py0 目标点的纬度坐标
     * @param px1 目标线的起点(终点)经度坐标
     * @param py1 目标线的起点(终点)纬度坐标
     * @param px2 目标线的终点(起点)经度坐标
     * @param py2 目标线的终点(起点)纬度坐标
     * @return
     */
    public static boolean isPointOnLine(double px0, double py0, double px1,
                                        double py1, double px2, double py2) {
        boolean flag = false;
        // 无限小的正数
        double ESP = 1e-9;
        if ((Math.abs(Multiply(px0, py0, px1, py1, px2, py2)) < ESP)
                && ((px0 - px1) * (px0 - px2) <= 0)
                && ((py0 - py1) * (py0 - py2) <= 0)) {
            flag = true;
        }
        return flag;
    }

    public static double Multiply(double px0, double py0, double px1, double py1,
                                  double px2, double py2) {
        return ((px1 - px0) * (py2 - py0) - (px2 - px0) * (py1 - py0));
    }

    /**
     * 求两点之间的距离(km)
     *
     * @param lng1 A点经度
     * @param lat1 A点纬度
     * @param lng2 B点经度
     * @param lat2 B点纬度
     * @return 两点距离
     */
    public static double getDistance(double lng1, double lat1, double lng2, double lat2) {
        // A经弧度
        double radiansAX = Math.toRadians(lng1);
        // A纬弧度
        double radiansAY = Math.toRadians(lat1);
        // B经弧度
        double radiansBX = Math.toRadians(lng2);
        // B纬弧度
        double radiansBY = Math.toRadians(lat2);
        // 公式中“cosβ1cosβ2cos（α1-α2）+sinβ1sinβ2”的部分，得到∠AOB的cos值
        double cos = Math.cos(radiansAY) * Math.cos(radiansBY) * Math.cos(radiansAX - radiansBX)
                + Math.sin(radiansAY) * Math.sin(radiansBY);

        // 反余弦值
        double acos = Math.acos(cos);
        // 最终结果
        return EARTH_RADIUS * acos;
    }





        //计算a, b两个点的距离，单位千米
    public static double getDistance2Point(Point p1, Point p2) {
        double longitude1 = p1.getLongitude();
        double latitude1 = p1.getLatitude();
        double longitude2 = p2.getLongitude();
        double latitude2 = p2.getLatitude();

        double radLat1 = rad(latitude1);
        double radLat2 = rad(latitude2);
        double pd1 = radLat1 - radLat2;
        double pd2 = rad(longitude1) - rad(longitude2);

        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(pd1 / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(pd2 / 2), 2)));
        s = s * EARTH_RADIUS;
        s = Math.round(s * 10000) / 10000;
        return s;
    }

    //转化为弧度（rad）
    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }





}
